﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using FamilyBook.Core.Entities;
using FamilyBook.Core.Repositories;

namespace FamilyBook.Core.Services
{
    public sealed class CounterpartyService
    {
        private readonly GeneralService<Person, int> _personServie;
        private readonly GeneralService<Organization, int> _orgService;

        public CounterpartyService(GeneralService<Person, int> personService,
            GeneralService<Organization, int> orgService)
        {
            if (personService == null)
                throw new ArgumentNullException("personService");
            if (orgService == null)
                throw new ArgumentNullException("orgService");

            _personServie = personService;
            _orgService = orgService;
        }

        public Person CreatePerson(Person person)
        {
            return _personServie.Create(person);
        }
        public Person GetPerson(int personId)
        {
            return _personServie.GetDetails(personId);
        }
        public IEnumerable<Person> GetPersons()
        {
            return _personServie.GetItemsList();
        }
        public void DeletePerson(int personId)
        {
            _personServie.DeleteById(personId);
        }

        public Organization CreateOrganization(Organization organization)
        {
            return _orgService.Create(organization);
        }
        public Organization GetOrganization(int organizationId)
        {
            return _orgService.GetDetails(organizationId);
        }
        public IEnumerable<Organization> GetOrganizations()
        {
            return _orgService.GetItemsList();
        }
        public void DeleteOrganization(int organizationId)
        {
            _orgService.DeleteById(organizationId);
        }

        public void AddPersonToOrganization(int personId, int organizationId)
        {
            AddPersonsToOrganization(new int[] {personId}, organizationId);
        }
        public void AddPersonsToOrganization(IEnumerable<int> personIds, int organizationId)
        {
            if (personIds == null)
                throw new ArgumentNullException("personIds");

            Organization org = _orgService.GetDetails(organizationId);
            if (org.Persons != null)
                personIds = personIds.Except(org.Persons.Select(x => x.CounterpartyId));
            else
                org.Persons = new Collection<Person>();

            if (personIds.Any())
            {
                personIds.Select(x => _personServie.GetDetails(x)).ToList().ForEach(x => org.Persons.Add(x));
                _orgService.Update(org);
            }
        }

        public void RemovePersonFromOrganization(int personId, int organizationId)
        {
            RemovePersonsFromOrganization(new int[] {personId}, organizationId);
        }
        public void RemovePersonsFromOrganization(IEnumerable<int> personIds, int organizationId)
        {
            if (personIds == null)
                throw new ArgumentNullException("personIds");

            Organization org = _orgService.GetDetails(organizationId);
            if (org.Persons == null)
                return;

            foreach (int personId in personIds)
            {
                Person orgPerson = org.Persons.FirstOrDefault(x => x.CounterpartyId == personId);
                if (orgPerson != null)
                    org.Persons.Remove(orgPerson);
            }
            _orgService.Update(org);
        }
    }
}
